# -*- coding: utf-8 -*-
# @Time    : 2020/3/16 下午8:16
# @Author  : lilong


"""
回调3：
（1）定义抽象类，定义抽象函数；
（2）定义子类，并实现抽象函数；
----------------
（3）定义接口类，接口交互实现；
（4）接口类的交互函数中传入实现抽象类的具体类；

"""

from abc import ABCMeta, abstractmethod


"""
# 代码框架2：面向对象的实现方式
"""


class Strategy(metaclass=ABCMeta):
    """抽象类"""

    @abstractmethod
    def algorithm(self, *args, **kwargs):
        """定义算法"""
        pass


class StrategyA(Strategy):
    """策略A"""

    def algorithm(self, *args, **kwargs):
        print("算法A的实现...")


class StrategyB(Strategy):
    """策略B"""

    def algorithm(self, *args, **kwargs):
        print("算法B的实现...")


class Context:
    """上下文环境接口类"""

    def interface(self, strategy, *args, **kwargs):
        """交互接口"""

        print("回调执行前的操作")
        strategy.algorithm()
        print("回调执行后的操作")


# # 框架2的调用方式
# context = Context()
# context.interface(StrategyA())
# context.interface(StrategyB())
# print("\n\n")


# ********************基于框架的实现2**********************
class Skill(metaclass=ABCMeta):
    """技能的抽象类"""

    @abstractmethod
    def performance(self):
        """技能表演"""
        pass


class NewEmployee:
    """公司新员工"""

    def __init__(self, name):
        """初始化"""
        self.__name = name

    def doPerformance(self, skill):
        """执行函数：传入的skill函数执行固定的performance函数"""

        print(self.__name + "的表演:", end="")
        skill.performance()


class Sing(Skill):
    """唱歌"""

    def performance(self):
        print("唱一首歌")


class Joke(Skill):
    """说段子"""

    def performance(self):
        print("说一搞笑段子")


class Dling(Skill):
    """拉Ukulele"""

    def performance(self):
        print("拉一曲Ukulele")


class PerformMagicTricks(Skill):
    """表演魔术"""

    def performance(self):
        print("神秘魔术")


class Skateboarding(Skill):
    """玩滑板"""

    def performance(self):
        print("酷炫滑板")


def StrategySkill():
    """接口函数中传入子类作为参数。
    接口类、子类的定义都是在抽象类定义好之后进行的。
    具体的功能实现是通过接口实现的。
    """
    helen = NewEmployee("Helen")
    helen.doPerformance(Sing())
    frank = NewEmployee("Frank")
    frank.doPerformance(Dling())
    jacky = NewEmployee("Jacky")
    jacky.doPerformance(Joke())
    chork = NewEmployee("Chork")
    chork.doPerformance(PerformMagicTricks())
    Kerry = NewEmployee("Kerry")
    Kerry.doPerformance(Skateboarding())


if __name__ == '__main__':
    StrategySkill()
